home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1993 / MacHack 1993.toast / MacHack™ 1987-1992 / MacHack™ '90 / Source Code ƒ / MPW C ƒ / SonOfGrepƒ / Tools.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-01-20  |  7.6 KB  |  499 lines  |  [TEXT/MPS ]

  1. /* TOOLS.C: expression parser used by grep. */
  2.  
  3. #include    <stdio.h>
  4. #include    "tools.h"
  5.  
  6. /* MJS: This function returns a char pointer */
  7. char * amatch(lin,pat,boln)
  8. char    *lin, *boln ;
  9. TOKEN    *pat ;
  10. {
  11.     char    *bocl, *rval, *strstart ;
  12. #ifdef    DEBUG
  13.     fprintf(stderr, "amatch entered\n") ;
  14. #endif
  15.     if (pat==0)
  16.         return(0) ;
  17.     strstart=lin ;
  18.     while(pat)
  19.     {
  20.         if(pat->tok == CLOSURE && pat->next)
  21.         {
  22.             pat = pat->next ;
  23.             bocl = lin ;
  24.             while(*lin && omatch(&lin, pat))  ;
  25.             if(pat = pat->next)
  26.             {
  27.                 while(bocl <= lin)
  28.                 {
  29.                     if(rval = amatch(lin, pat, boln))
  30.                     {
  31.                         return(rval) ;
  32.                     }
  33.                     else
  34.                         --lin ;
  35.                 }
  36.                 return(0) ;
  37.             }
  38.         }
  39.         else if(omatch(&lin, pat, boln))
  40.         {
  41.             pat=pat->next ;
  42.         }
  43.         else
  44.         {
  45.             return(0) ;
  46.         }
  47.     }
  48.     return(maximum(strstart, --lin)) ;
  49. }
  50.  
  51.  
  52. delete (ch, str)
  53. int        ch ;
  54. char    *str ;
  55. {
  56. #ifdef    DEBUG
  57.     fprintf(stderr, "delete entered.\n") ;
  58. #endif
  59.     ch &= 0xff ;
  60.     while(*str && *str != ch)
  61.         str++ ;
  62.     while(*str)
  63.     {
  64.         *str = *(str+1) ;
  65.         str++ ;
  66.     }
  67. }
  68.  
  69.  
  70.  
  71. int dodash (delim, src, dest, maxccl)
  72. int    delim, maxccl ;
  73. char    **src, *dest ;
  74. {
  75.     char    *dstart ;
  76.     int    k, at_begin ;
  77.     char        *sptr ;
  78. #ifdef    DEBUG
  79.     fprintf(stderr, "dodash entered\n") ;
  80. #endif
  81.     dstart = dest ;
  82.     sptr = *src ;
  83.     at_begin = 1 ;
  84.     while(*sptr && (*sptr != delim) && (dstart-dest < maxccl))
  85.     {
  86.         if(*sptr == ESCAPE)
  87.         {
  88.             *dest++ = esc(&sptr) ;
  89.             sptr++ ;
  90.         }
  91.         else if (*sptr != '-')
  92.             *dest++ = *sptr++ ;
  93.         else if (at_begin || *(sptr+1) == delim)
  94.             *dest++ = '-' ;
  95.         else if ( *(sptr-1)<= *(sptr+1))
  96.         {
  97.             sptr++ ;
  98.             for(k= *(sptr-2); ++k <= *sptr;)
  99.                 *dest++ = k ;
  100.             sptr++ ;
  101.         }
  102.         else
  103.         {
  104.             return(0) ;
  105.         }
  106.         at_begin = 0 ;
  107.     }
  108.     *dest++ = '\000' ;
  109.     *src = sptr ;
  110.     return(dest - dstart) ;
  111. }
  112.  
  113.  
  114. int esc (s)
  115. char    **s ;
  116. {
  117.     int    rval ;
  118. #ifdef    DEBUG
  119.     fprintf(stderr, "esc entered.\n") ;
  120. #endif
  121.     if(**s != ESCAPE)
  122.     {
  123.         rval = **s ;
  124.     }
  125.     else
  126.     {
  127.         (*s)++ ;
  128.         switch(toupper(**s))
  129.         {
  130.         case    '\000':    rval = ESCAPE ;    break ;
  131.         case    'S':    rval = ' ' ;    break ;
  132.         case    'N':    rval = '\n' ;    break ;
  133.         case    'T':    rval = '\t' ;    break ;
  134.         case    'B':    rval = '\b' ;    break ;
  135.         case    'R':    rval = '\r' ;    break ;
  136.         default:    rval = **s ;    break ;
  137.         }
  138.     }
  139.     return(rval) ;
  140. }
  141.  
  142.  
  143.  
  144.  
  145. TOKEN *getpat (arg)
  146. char    *arg ;
  147. {
  148. #ifdef    DEBUG
  149.     fprintf(stderr, "getpat entered.\n") ;
  150. #endif
  151.     return(makepat(arg, '\000')) ;
  152. }
  153.  
  154.  
  155.  
  156. insert (ch, str)
  157. int    ch ;
  158. char    *str ;
  159. {
  160.     char    *bp ;
  161. #ifdef    DEBUG
  162.     fprintf(stderr, "insert entered.\n") ;
  163. #endif
  164.     bp = str ;
  165.     while(*str)
  166.         str++ ;
  167.     do
  168.     {
  169.         *(str+1) = *str ;
  170.         str-- ;
  171.     } while (str >= bp) ;
  172.     *bp = ch ;
  173. }
  174.  
  175.  
  176.  
  177. char *in_string (delim, str)
  178. int    delim ;
  179. char    *str ;
  180. {
  181. #ifdef    DEBUG
  182.     fprintf(stderr, "in_string entered.\n") ;
  183. #endif
  184.     delim &= 0x7f ;
  185.     while(*str && *str != delim)
  186.         str++ ;
  187.     return(*str ? str : 0) ;
  188. }
  189.  
  190.  
  191.  
  192.  
  193. int isalphanum (c)
  194. int    c ;
  195. {
  196. #ifdef    DEBUG
  197.     fprintf(stderr, "isalphanum entered.\n") ;
  198. #endif
  199.     return(    ('a' <= c && c <= 'z') ||
  200.         ('A' <= c && c <= 'Z') ||
  201.         ('0' <= c && c <= '9')
  202.           ) ;
  203. }
  204.  
  205.  
  206.  
  207.  
  208. TOKEN *makepat (arg, delim)
  209. char    *arg ;
  210. int    delim ;
  211. {
  212.     TOKEN    *head, *tail ;
  213.     TOKEN    *ntok ;
  214.     char    buf[CLS_SIZE] ;
  215.     int    error ;
  216.     char    *malloc() ;
  217. #ifdef    DEBUG
  218.     fprintf(stderr, "makepat entered.\n") ;
  219. #endif
  220.     if(*arg=='\0' || *arg==delim || *arg=='\n' || *arg==CLOSURE)
  221.         return(0) ;
  222.     error = 0 ;
  223.     head = 0 ;
  224.     tail = 0 ;
  225.     while(*arg && *arg != delim && *arg != '\n' && !error)
  226.     {
  227.         ntok = malloc(TOKSIZE) ;
  228.         ntok->string = &(ntok->lchar) ;
  229.         ntok->lchar = '\000' ;
  230.         ntok->next = 0 ;
  231.         switch(*arg)
  232.         {
  233.         case ANY:    ntok->tok = ANY ;    break ;
  234.         case BOL:    if(head==0)
  235.                     ntok->tok = BOL ;
  236.                 else
  237.                     error = 1 ;
  238.                 break ;
  239.         case EOL:    if(*(arg+1) == delim|| *(arg+1) == '\000'
  240.                             || *(arg+1) == '\n')
  241.                     ntok->tok = EOL ;
  242.                 else
  243.                     error = 1 ;
  244.                 break ;
  245.         case CCL:    if(*(arg+1) == NEGATE)
  246.                 {
  247.                     ntok->tok = NCCL ;
  248.                     arg += 2 ;
  249.                 }
  250.                 else
  251.                 {
  252.                     ntok->tok = CCL ;
  253.                     arg++ ;
  254.                 }
  255.                 error = dodash(CCLEND, &arg, buf, CLS_SIZE) ;
  256.                 if (error != 0)
  257.                 {
  258.                     ntok->string = malloc(error) ;
  259.                     strcpy(ntok->string, buf) ;
  260.                     error = 0 ;
  261.                 }
  262.                 break ;
  263.         case CLOSURE:    if(head != 0)
  264.                 {
  265.                     switch (tail->tok)
  266.                     {
  267.                     case BOL:
  268.                     case EOL:
  269.                     case CLOSURE:    return(0) ;
  270.                     default:    ntok->tok = CLOSURE ;
  271.                     }
  272.                 }
  273.                 break ;
  274.         default:    ntok->tok = LITCHAR;
  275.                 ntok->lchar = esc(&arg) ;
  276.         }
  277.         if(error || ntok == 0)
  278.         {
  279.             unmakepat(head) ;
  280.             return(0) ;
  281.         }
  282.         else if (head == 0)
  283.         {
  284.             ntok->next = 0 ;
  285.             head = tail = ntok ;
  286.         }
  287.         else if (ntok->tok != CLOSURE)
  288.         {
  289.             tail->next = ntok ;
  290.             ntok->next = tail ;
  291.             tail = ntok ;
  292.         }
  293.         else if(head != tail)
  294.         {
  295.             (tail->next)->next = ntok ;
  296.             ntok->next = tail ;
  297.         }
  298.         else
  299.         {
  300.             ntok->next = head ;
  301.             tail->next = ntok ;
  302.             head = ntok ;
  303.         }
  304.         arg++ ;
  305.     }
  306.     tail->next = 0;
  307.     return(head) ;
  308. }
  309.  
  310.  
  311.  
  312.  
  313. char *matchs (line, pat, ret_endp)
  314. char    *line ;
  315. TOKEN    *pat ;
  316. int    ret_endp ;
  317. {
  318.     char    *rval, *bptr ;
  319. #ifdef    DEBUG
  320.     fprintf(stderr, "matchs entered.\n") ;
  321. #endif
  322.     bptr = line ;
  323.     while(*line)
  324.     {
  325.         if((rval = amatch(line, pat, bptr)) == 0)
  326.         {
  327.             line++ ;
  328.         }
  329.         else
  330.         {
  331.             rval = ret_endp ? rval : line ;
  332.             break ;
  333.         }
  334.     }
  335.     return(rval) ;
  336. }
  337.  
  338.  
  339.  
  340.  
  341. stoupper (str)
  342. char    *str ;
  343. {
  344.     char    *rval ;
  345. #ifdef    DEBUG
  346.     fprintf(stderr, "stoupper entered.\n") ;
  347. #endif
  348.     rval = str ;
  349.     while(*str)
  350.     {
  351.         if('a' <= *str && *str <= 'z')
  352.             *str -= ('a' - 'A') ;
  353.         str++ ;
  354.     }
  355. }
  356.  
  357.  
  358.  
  359.  
  360. int maximum (x, y)
  361. int    x, y ;
  362. {
  363.     return ((x>y) ? x : y) ;
  364. }
  365.  
  366.  
  367.  
  368.  
  369. int omatch (linp, pat, boln)
  370. char    **linp, *boln ;
  371. TOKEN    *pat ;
  372. {
  373.     int    advance ;
  374. #ifdef    DEBUG
  375.     fprintf(stderr, "omatch entered.\n") ;
  376. #endif
  377.     advance = -1 ;
  378.     if(**linp)
  379.     {
  380.         switch(pat->tok)
  381.         {
  382.         case LITCHAR:    if(**linp == pat->lchar)
  383.                     advance = 1 ;
  384.                 break ;
  385.         case BOL:    if(*linp == boln)
  386.                     advance = 0 ;
  387.                 break ;
  388.         case ANY:    if(**linp != '\n')
  389.                     advance = 1 ;
  390.                 break ;
  391.         case EOL:    if(**linp == '\n')
  392.                     advance = 0 ;
  393.                 break ;
  394.         case CCL:    if(in_string(**linp, pat->string))
  395.                     advance = 1;
  396.                 break ;
  397.         case NCCL:    if( ! in_string (**linp, pat->string))
  398.                     advance = 1 ;
  399.                 break ;
  400.         default:    printf("omatch: can't happen\n") ;
  401.         }
  402.     }
  403.     if(advance >= 0)
  404.         *linp += advance ;
  405.     return(++advance) ;
  406. }
  407.  
  408.  
  409.  
  410.  
  411. pr_line (ln)
  412. char    *ln ;
  413. {
  414. #ifdef    DEBUG
  415.     fprintf(stderr, "pr_line entered.\n") ;
  416. #endif
  417.     for( ; *ln; ln++)
  418.     {
  419.         if((' ' <= *ln) && (*ln <= '~'))
  420.             putchar(*ln) ;
  421.         else
  422.         {
  423.             printf("\\0x%02x", *ln) ;
  424.             if(*ln == '\n')
  425.                 putchar('\n') ;
  426.         }
  427.     }
  428. }
  429.  
  430.  
  431.  
  432.  
  433. pr_tok (head)
  434. TOKEN    *head ;
  435. {
  436.     char    *str ;
  437. #ifdef    DEBUG
  438.     fprintf(stderr, "pr_token netered.\n") ;
  439. #endif
  440.     for( ; head; head = head->next)
  441.     {
  442.         switch(head->tok)
  443.         {
  444.         case BOL:    str="BOL" ;    break ;
  445.         case EOL:    str="EOL" ;    break ;
  446.         case ANY:    str="ANY" ;    break ;
  447.         case LITCHAR:    str="LITCHAR" ;    break ;
  448.         case ESCAPE:    str="ESCAPE" ;    break ;
  449.         case CCL:    str="CCL" ;    break ;
  450.         case CCLEND:    str="CCLEND" ;    break ;
  451. /*        case NEGATE:    str="NEGATE" ;    break ;  */  /* dup case constant */
  452.         case NCCL:    str="NCCL" ;    break ;
  453.         case CLOSURE:    str="CLOSURE" ;    break ;
  454.         default:    str="**** unknown ****" ;
  455.         }
  456.         printf("%-8s at: 0x%x, ", str, head) ;
  457.         if(head->tok == CCL || head->tok == NCCL)
  458.             printf("string =[%s]=, ", head->string) ;
  459.         else if (head->tok == LITCHAR)
  460.             printf("lchar = %c, ", head->lchar) ;
  461.         printf("next = 0x%x\n", head->next) ;
  462.     }
  463.     putchar("\n") ;
  464. }
  465.  
  466.  
  467.  
  468.  
  469. unmakepat (head)
  470. TOKEN    *head ;
  471. {
  472.     TOKEN *old_head ;
  473. #ifdef    DEBUG
  474.     fprintf(stderr, "unmakepat entered.\n") ;
  475. #endif
  476.     while(head)
  477.     {
  478.         switch(head->tok)
  479.         {
  480.         case CCL:
  481.         case NCCL:    free(head->string) ;
  482.         default:    old_head = head ;
  483.                 head = head->next ;
  484.                 free(old_head) ;
  485.                 break ;
  486.         }
  487.     }
  488. }
  489.  
  490.  
  491. /* MJS: this function retrieves tool name */
  492. char * ToolName() {
  493. int i;
  494.     for (i = 0; FullToolName[i] != '\0'; i++);    /* end of string */
  495.     for (; (FullToolName[i]!=':')&(i>0); i--);    /* back up to last colon */
  496.     if (FullToolName[i]==':') i++;                /* dont return last colon */
  497.     return(&FullToolName[i]);                    /* done */
  498. }    /* end of ToolName */
  499.